package com.fangqiang.sprint_boot_web1.mybatisinterceptor;

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.update.Update;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.stereotype.Component;

import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;

@Component

//只能支持下面4个接口的拦截
@Intercepts({@Signature(type = StatementHandler.class, method = "update", args = {Statement.class})})
//@Intercepts({@Signature(type = ParameterHandler.class, method = "setParameters", args = {PreparedStatement.class})})
//@Intercepts({@Signature(type = ResultHandler.class, method = "handleResult", args = {ResultContext.class})})
//@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})

public class MybatisIntercepts2 implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        PreparedStatement arg = (PreparedStatement)invocation.getArgs()[0];

        // *** 获取完整的sql， 但是这个获取sql的方法太取巧了
        String sql = arg.toString().split(":")[1];

        Update parse = (Update) CCJSqlParserUtil.parse(sql);

        // 解析sql获取update的字段名，和字段值
        // 如果需要获取Expression中的值，可以通过反射获取getValue方法
        Map<String, Expression> collect = parse.getUpdateSets().stream().collect(Collectors.toMap(
                e -> e.getColumns().get(0).getColumnName(),
                e -> e.getExpressions().get(0)
        ));

        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        // 可以接收配置的属性
    }
}